package com.ruoyi.quality.service.impl;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.List;

import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.quality.domain.ItemInfo;
import com.ruoyi.quality.domain.TInspectionFormItem;
import com.ruoyi.quality.domain.TInspectionFormItem1;
import com.ruoyi.safe.domain.CommonProject;
import com.ruoyi.safe.mapper.CommonProjectMapper;
import freemarker.template.Template;
import org.apache.commons.io.FileUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.beans.factory.annotation.Autowired;
import freemarker.template.Configuration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.quality.mapper.TInspectionFormMapper;
import com.ruoyi.quality.domain.TInspectionForm;
import com.ruoyi.quality.service.ITInspectionFormService;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 整改巡检单记录Service业务层处理
 * 
 * @author mahl2
 * @date 2024-07-02
 */
@Service
public class TInspectionFormServiceImpl implements ITInspectionFormService 
{
    @Autowired
    private TInspectionFormMapper tInspectionFormMapper;
    @Autowired
    private CommonProjectMapper commonProjectMapper;
    private Configuration configuration = new Configuration();
    @Value("${minio.url}")
    private String minioUrl;
    /**
     * 查询整改巡检单记录
     * 
     * @param id 整改巡检单记录主键
     * @return 整改巡检单记录
     */
    @Override
    public TInspectionForm selectTInspectionFormById(String id)
    {
        return tInspectionFormMapper.selectTInspectionFormById(id);
    }

    /**
     * 查询整改巡检单记录列表
     * 
     * @param tInspectionForm 整改巡检单记录
     * @return 整改巡检单记录
     */
    @Override
    public List<TInspectionForm> selectTInspectionFormList(TInspectionForm tInspectionForm)
    {
        return tInspectionFormMapper.selectTInspectionFormList(tInspectionForm);
    }

    /**
     * 新增整改巡检单记录
     * 
     * @param tInspectionForm 整改巡检单记录
     * @return 结果
     */
    @Override
    public void insertTInspectionForm(TInspectionForm tInspectionForm, HttpServletResponse response, HttpServletRequest request)
    {
        OutputStream os = null;
        InputStream is = null;
        Map<String, Object> dataMap = new HashMap<String, Object>();
        configuration.setDefaultEncoding("UTF-8");
        /*获取项目信息*/
        CommonProject project = commonProjectMapper.selectCommonProjectById(Long.parseLong(tInspectionForm.getProjectId()));
        /*设置项目信息*/
        tInspectionForm.setProjectNameBase(project.getName());
        tInspectionForm.setProjectOverview(project.getProjectOverview());
        /*处理word中所需要的数据*/
        getData(dataMap,tInspectionForm);
        /*获取ftl模板路径*/
        configuration.setClassForTemplateLoading(this.getClass(), "/");//模板文件所在路径
        Template t = null;
        try {
            t = configuration.getTemplate("test.ftl"); //获取模板文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        String outPutFileName =  RuoYiConfig.getProfile()+File.separator+"exportFile"+File.separator+DateUtils.getDate()+File.separator + "exportFile_"+ IdUtil.getSnowflakeNextId() + ".doc"; //导出文件
        File outFile = new File(outPutFileName); //导出文件
        Writer out = null;
        try {
            if (!new File(RuoYiConfig.getProfile()+File.separator+"exportFile"+File.separator+DateUtils.getDate()).exists()) {
                // 文件夹不存在，创建文件夹
                new File(RuoYiConfig.getProfile()+File.separator+"exportFile"+File.separator+DateUtils.getDate()).mkdirs();
            }
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
            t.process(dataMap, out);
            // 生成Word文档
            XWPFDocument document = new XWPFDocument();
            XWPFParagraph paragraph = document.createParagraph();
            XWPFRun run = paragraph.createRun();
            run.setText(out.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        /*设置基础信息*/
        LoginUser loginUser = SecurityUtils.getLoginUser();
        tInspectionForm.setCreateTime(DateUtils.getNowDate());
        tInspectionForm.setUpdateTime(DateUtils.getNowDate());
        tInspectionForm.setCreateBy(loginUser.getUsername());
        tInspectionForm.setUpdateBy(loginUser.getUsername());
        tInspectionForm.setFormPath(outPutFileName);
        tInspectionForm.setId(String.valueOf(IdUtil.getSnowflakeNextId()));
        tInspectionFormMapper.insertTInspectionForm(tInspectionForm);
        try{
            // 设置response方式,使执行此controller时候自动出现下载页面,而非直接使用excel打开
            response.setContentType("APPLICATION/OCTET-STREAM;charset=UTF-8");
            String wordName = java.net.URLEncoder.encode("巡检单", "UTF8");
            response.setHeader("Content-Disposition", "attachment; filename=" + wordName);
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            os =  response.getOutputStream();
            is = new FileInputStream(outPutFileName);
            byte[] b = new byte[2048];
            int length;
            while ((length = is.read(b)) > 0) {
                os.write(b, 0, length);
            }

        }catch ( Exception e){
            e.printStackTrace();
        }finally {
            try {
                os.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            /*清理word产生的临时图片*/
            try {
                FileUtils.deleteDirectory(new File(RuoYiConfig.getProfile()+File.separator+DateUtils.getDate()+File.separator));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 修改整改巡检单记录
     * 
     * @param tInspectionForm 整改巡检单记录
     * @return 结果
     */
    @Override
    public int updateTInspectionForm(TInspectionForm tInspectionForm)
    {
        tInspectionForm.setUpdateTime(DateUtils.getNowDate());
        return tInspectionFormMapper.updateTInspectionForm(tInspectionForm);
    }

    /**
     * 批量删除整改巡检单记录
     * 
     * @param ids 需要删除的整改巡检单记录主键
     * @return 结果
     */
    @Override
    public int deleteTInspectionFormByIds(String[] ids)
    {
        return tInspectionFormMapper.deleteTInspectionFormByIds(ids);
    }

    /**
     * 删除整改巡检单记录信息
     * 
     * @param id 整改巡检单记录主键
     * @return 结果
     */
    @Override
    public int deleteTInspectionFormById(String id)
    {
        return tInspectionFormMapper.deleteTInspectionFormById(id);
    }

    @Override
    public void exportInfo(TInspectionForm tInspectionForm, HttpServletResponse response, HttpServletRequest request) {
        tInspectionForm =  tInspectionFormMapper.selectTInspectionFormById(tInspectionForm.getId());
        try{
            // 设置response方式,使执行此controller时候自动出现下载页面,而非直接使用excel打开
            response.setContentType("APPLICATION/OCTET-STREAM;charset=UTF-8");
            String wordName = java.net.URLEncoder.encode("巡检单", "UTF8");
            response.setHeader("Content-Disposition", "attachment; filename=" + wordName);
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            OutputStream os =  response.getOutputStream();
            InputStream is = new FileInputStream(tInspectionForm.getFormPath());
            byte[] b = new byte[2048];
            int length;
            while ((length = is.read(b)) > 0) {
                os.write(b, 0, length);
            }
            os.flush();
            os.close();
        }catch ( Exception e){
            e.printStackTrace();
        }
    }

    private String getImgBase64(String imageUrl)  {
        // 本地资源路径
        String localPath = RuoYiConfig.getProfile()+File.separator+DateUtils.getDate()+File.separator;
        /*图片后缀*/
        String laseIndex = imageUrl.substring(imageUrl.lastIndexOf(".")+ 1,imageUrl.length());
        /** 图片存储至本地文件名称 **/
        String fileName = imageUrl.substring(imageUrl.lastIndexOf("/")+ 1,imageUrl.length());
        /*图片临时存储文件名*/
        String localFileName = "temp_"+fileName;
        /*通过图片流方法 通过图片地址获取minio图片流base64编码*/
        saveImgToLocal(imageUrl,localPath,localFileName);
        try {
            BufferedImage image = ImageIO.read(new File(localPath+localFileName));
            // 设置新的宽度和高度
            int newWidth = 520; // 替换为目标宽度
            int newHeight = 320; // 替换为目标高度
            BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, image.getType());
            resizedImage.getGraphics().drawImage(image.getScaledInstance(newWidth, newHeight, BufferedImage.SCALE_SMOOTH), 0, 0, null);

            // 写入新的图片到文件系统
            String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
            File outputFile = new File(new File(localPath+localFileName).getParent(), "resized_"+new File(localPath+localFileName).getName().substring(0, new File(localPath+localFileName).getName().lastIndexOf(".")) + "." + extension);
            ImageIO.write(resizedImage, extension, outputFile);

            // 将BufferedImage转换为Base64编码的字符串
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(resizedImage, "png", outputStream);
            byte[] imageBytes = outputStream.toByteArray();
            String base64String = "data:image/"+laseIndex+";base64,"+Base64.getEncoder().encodeToString(imageBytes);
//            System.out.println(new File(localPath+"resized_"+localFileName).delete()==true?"清理成功1":"清理失败");
//            Thread.sleep(1000);
//            System.out.println(new File(localPath+localFileName).delete()==true?"清理成功2":"清理失败");
            return base64String;
        } catch (IOException  e) {
            e.printStackTrace();
        }
        return null;
    }

    private void saveImgToLocal(String imageUrl, String localPath, String localFileName) {
        InputStream inputStream = null;
        ByteArrayOutputStream data = null;
        try{
            // 创建一个URL对象
            URL url = new URL(imageUrl);
            // 打开连接
            inputStream = url.openStream();

            // 使用ByteArrayOutputStream来读取InputStream的内容
            data = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                data.write(buffer, 0, length);
            }
            // 将字节数组转换为Base64编码
            byte[] imageBytes = data.toByteArray();
//            String base64String = Base64.getEncoder().encodeToString(imageBytes);

            try {
                if (!new File(localPath).exists()) {
                    // 文件夹不存在，创建文件夹
                    new File(localPath).mkdirs();
                }
               FileOutputStream imageOutFile = new FileOutputStream(new File(localPath+localFileName));
                // 将字节数据写入文件
                imageOutFile.write(imageBytes);
                System.out.println("图片已经被写入到：" + localPath+localFileName);
            } catch (IOException e) {
                System.out.println("发生错误：" + e.getMessage());
            }

            // 关闭流

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                data.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    private void getData(Map<String, Object> dataMap,TInspectionForm tInspectionForm) {
        /*处理word基础数据*/
        dataMap.put("name",tInspectionForm.getProjectNameBase());
        dataMap.put("title",tInspectionForm.getProjectName());
        dataMap.put("time",DateUtils.getDate());
        dataMap.put("unit","吉林省路桥工程（集团）有限公司安质环保部");
        dataMap.put("titleText",tInspectionForm.getFormDes());
        dataMap.put("titleLaneOne","一、安全质量问题");
        dataMap.put("titleLaneTwo","二、整改要求");
        dataMap.put("rectificationDeadline",tInspectionForm.getRectificationDeadline());
        /*项目概况*/
        dataMap.put("content", tInspectionForm.getProjectOverview());
        List itemInfoList = new ArrayList();

        for(int i=0 ; i<tInspectionForm.getItemList().size() ;  i++){
            ItemInfo itemInfo = new ItemInfo();
            List itemList = new ArrayList();
            /*质量问题描述*/
            itemInfo.setDescription(tInspectionForm.getItemList().get(i).getQuestionInfo());
            for(int j=0;j<tInspectionForm.getItemList().get(i).getPidIdsList().size();j++){
                itemList.add(getImgBase64(minioUrl+"/"+tInspectionForm.getItemList().get(i).getPidIdsList().get(j).getBucket()+"/"+tInspectionForm.getItemList().get(i).getPidIdsList().get(j).getName()));
            }
            itemInfo.setList(itemList);
            itemInfoList.add(itemInfo);
        }

        List requirementInfoList = new ArrayList();
        for(int j=0;j<tInspectionForm.getRectificationRequirementsList().size() ; j++){
            ItemInfo itemInfo = new ItemInfo();
            itemInfo.setDescription(tInspectionForm.getRectificationRequirementsList().get(j).getItemOrder()+"、"+tInspectionForm.getRectificationRequirementsList().get(j).getItemDes());
            requirementInfoList.add(itemInfo);
        }
        dataMap.put("requirementInfoList", requirementInfoList);
        dataMap.put("itemInfoList", itemInfoList);
    }
}
